home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ML_VECTB.ZIP / SOURCE / VECTBALL.PAS < prev    next >
Pascal/Delphi Source File  |  1996-05-04  |  18KB  |  715 lines

  1. {
  2.  
  3.    3D Vector Balls
  4.    by Maple Leaf, 1996
  5.    version 1.2 (update 3: 4th May 1996, -> system timer support added + speedups)
  6.    -----------------------------------------------------------------------
  7.    Using XMODE v1.1 and ENGINE3D v3.0, both (C)Copywrong by Maple Leaf.
  8.    -----------------------------------------------------------------------
  9.    No comments are necessarry. Theoretically, the program's running speed
  10.    depends only on the video card's speed. Conclusion: buy a video accelerator! :)
  11.    Leaving the jokes away, the 3D engine works very fast for such a small
  12.    number of points (48), and xImageOvr routine (from XMODE 1.1) has
  13.    been optimized for speed (by me!:), so there shouldn't be speed problems
  14.    in running this shitty program. If there are some, well, blame your
  15.    computer; I THINK it's not my fault...
  16.  
  17. }
  18. uses engine3d, xmode, dosio, crt;
  19.  
  20. const
  21.   Forms      = 8;
  22.   MaxHeights = 256;
  23.   { Limits }
  24.   MaxRadius  = 150;
  25.   MaxH       = 100;
  26.  
  27.   PagMin:byte= 0;
  28.   PagMax:byte= 3;
  29.  
  30. type
  31.   BallType = array [0..10] of record
  32.                                 x,y  : integer;
  33.                                 data : array [byte] of byte;
  34.                               end;
  35.   FormType = record
  36.                dots : integer;
  37.                data : array [0..47] of record x,y,z:integer end;
  38.              end;
  39.  
  40. var
  41.   putLogo : boolean;
  42.   Ball  : array [0..2] of BallType;
  43.   Form  : array [0..Forms-1] of FormType;
  44.   pal   : array [byte] of record r,g,b:byte end;
  45.   origpal : array [byte] of record r,g,b:byte end;
  46.   capag, cvpag, cball : integer;
  47.   TiltStep, RotStep : Integer;
  48.   CFormModel : FormType; { Model for form-transforming }
  49.   CForm : FormType;      { Current form }
  50.   CFormNr : Integer;
  51.   CPoints : array [0..50] of record
  52.                               x     : integer;
  53.                               y     : integer;
  54.                               Zdist : longint;   { 8 bytes }
  55.                             end;
  56.   FCounter : word;
  57.   {}
  58.   Y_Val  : array [0..MaxHeights-1] of Integer;  { Heights }
  59.   YIndex : array [0..47] of Integer;  { Y index }
  60.   YSpd   : array [0..47] of Integer;  { * Y variation speed }
  61.   Rad    : array [0..47] of Integer;  { Radius for each trajectory }
  62.   RadSpd : array [0..47] of Integer;  { * Radius variation speed }
  63.   Ang    : array [0..47] of Integer;  { Angle for each trajectory }
  64.   AngSpd : array [0..47] of Integer;  { * Angle variation speed }
  65.   {}
  66.   ML_BitMap : array [0..2999] of byte; {3 Kb}
  67.  
  68.   old_int8 : pointer;
  69.   intr : array [byte] of pointer absolute 0:0;
  70.  
  71. const
  72.   Angles : array [0..Forms-1] of record RotA, TiltA : integer end = (
  73.                                                                 (RotA:2;TiltA:3),
  74.                                                                 (RotA:2;TiltA:3),
  75.                                                                 (RotA:-1;TiltA:3),
  76.                                                                 (RotA:2;TiltA:1),
  77.                                                                 (RotA:-2;TiltA:3),
  78.                                                                 (RotA:-3;TiltA:2),
  79.                                                                 (RotA:3;TiltA:1),
  80.                                                                 (RotA:-2;TiltA:1)
  81.                                                               );
  82.  
  83.   BallCol : array [0..Forms-1] of word = ( 0, 0, 0, 0, 0, 0, 0, 0 );
  84.  
  85. Procedure LoadData;
  86. var f:file;
  87. begin
  88.   Writeln('Loading data ...');
  89.   { red ball }
  90.   openforinput(f,'data\redball.tab','');
  91.   blockread(f,Ball[0],260*11);
  92.   closefile(f,'');
  93.   { blue ball }
  94.   openforinput(f,'data\blueball.tab','');
  95.   blockread(f,Ball[1],260*11);
  96.   closefile(f,'');
  97.   { green ball }
  98.   openforinput(f,'data\grnball.tab','');
  99.   blockread(f,Ball[2],260*11);
  100.   closefile(f,'');
  101.   { form #1 }
  102.   openforinput(f,'data\_init.bal','');
  103.   blockread(f,Form[0],290);
  104.   closefile(f,'');
  105.   { form #2 }
  106.   openforinput(f,'data\_sphere.bal','');
  107.   blockread(f,Form[1],290);
  108.   closefile(f,'');
  109.   { form #3 }
  110.   openforinput(f,'data\_cube.bal','');
  111.   blockread(f,Form[2],290);
  112.   closefile(f,'');
  113.   { form #4 }
  114.   openforinput(f,'data\_jupiter.bal','');
  115.   blockread(f,Form[3],290);
  116.   closefile(f,'');
  117.   { form #5 }
  118.   openforinput(f,'data\_2blobs.bal','');
  119.   blockread(f,Form[4],290);
  120.   closefile(f,'');
  121.   { form #6 }
  122.   openforinput(f,'data\_triangl.bal','');
  123.   blockread(f,Form[5],290);
  124.   closefile(f,'');
  125.   { form #7 }
  126.   openforinput(f,'data\_pyram.bal','');
  127.   blockread(f,Form[6],290);
  128.   closefile(f,'');
  129.   { form #8 }
  130.   openforinput(f,'data\_cross.bal','');
  131.   blockread(f,Form[7],290);
  132.   closefile(f,'');
  133.   { palette }
  134.   openforinput(f,'data\balls.pal','');
  135.   blockread(f,pal,768);
  136.   move(pal,origpal,768);
  137.   closefile(f,'');
  138.   { ML bitmap }
  139.   openforinput(f,'data\ml.btm','');
  140.   blockread(f,ML_BitMap,93*31+4);
  141.   closefile(f,'');
  142. end;
  143.  
  144. procedure Shit(s:string);
  145. var k,p:byte;
  146. const col:array[0..6] of byte = ( 8, 1, 3, 9, 11, 15, 7 );
  147. begin
  148.   for k:=1 to length(s) do begin
  149.     for p:=0 to 6 do begin
  150.       textattr:=col[p];
  151.       write(s[k],#8);
  152.       delay(15);
  153.     end;
  154.     write(s[k]);
  155.   end;
  156.   writeln;
  157. end;
  158.  
  159. Procedure DoneAll;
  160. begin
  161.   Shit('   ──--∙ by Maple Leaf, 1996 ∙-───');
  162.   Shit(' *  Hope you''ve enjoyed this shit  *');
  163. end;
  164.  
  165. Procedure UpdateForm1;near;assembler;
  166. asm
  167.   inc FCounter
  168.   cmp FCounter,350
  169.   jb @Slide
  170.   { First, update the form's index }
  171.   inc CFormNr
  172.   cmp CFormNr,Forms-1
  173.   jbe @Ok1
  174.   mov CFormNr,0
  175. @Ok1:
  176.   { Update the angles variation speed }
  177.   mov si,CFormNr
  178.   shl si,2
  179.   mov ax,word ptr Angles[si]    {Rot}
  180.   mov bx,word ptr Angles[si+2]  {Tilt}
  181.   mov RotStep,ax
  182.   mov TiltStep,bx
  183.   shr si,1
  184.   mov ax,word ptr BallCol[si]
  185.   mov CBall,ax
  186.   { Update form model }
  187.   mov ax,ds
  188.   mov es,ax
  189.   mov si,CFormNr
  190.   shl si,1
  191.   mov ax,si    { ax:=cformnr*2 }
  192.   shl si,4
  193.   add ax,si    { ax:=cformnr*2+cformnr*32 }
  194.   shl si,3
  195.   add si,ax    { si:=cformnr*2+cformnr*32+cformnr*256 = cformnr*290 }
  196.   add si,offset Form {!}
  197.   mov di,offset CFormModel
  198.   mov cx,145 {290/2}
  199.   rep movsw
  200.   { Reset counter }
  201.   mov FCounter,0
  202.   jmp @Outta
  203. @Slide:
  204.   { Slide to the form shown by CFormModel }
  205.   mov si,offset CForm + 2
  206.   mov di,offset CFormModel + 2
  207.   mov cx,48
  208. @Loop1:
  209.     {X}
  210.     mov ax,[si]
  211.     cmp ax,[di]
  212.     je @Next1
  213.     jl @Less1
  214.     dec ax
  215.     mov [si],ax
  216.     jmp @Next1
  217.   @Less1:
  218.     inc ax
  219.     mov [si],ax
  220.   @Next1:
  221.     {Y}
  222.     mov ax,[si+2]
  223.     cmp ax,[di+2]
  224.     je @Next2
  225.     jl @Less2
  226.     dec ax
  227.     mov [si+2],ax
  228.     jmp @Next2
  229.   @Less2:
  230.     inc ax
  231.     mov [si+2],ax
  232.   @Next2:
  233.     {Z}
  234.     mov ax,[si+4]
  235.     cmp ax,[di+4]
  236.     je @Next3
  237.     jl @Less3
  238.     dec ax
  239.     mov [si+4],ax
  240.     jmp @Next3
  241.   @Less3:
  242.     inc ax
  243.     mov [si+4],ax
  244.   @Next3:
  245.     add di,6  { Next coordinates }
  246.     add si,6  { -"- }
  247.   loop @Loop1
  248. @Outta:
  249. end;
  250.  
  251. procedure FastSort;near;assembler;  { "Fast" enough for such an application... }
  252. asm
  253.   push bp
  254.   mov si,4 + offset CPoints
  255.   mov cx,47
  256. @Loop1:
  257.     mov bp,cx               { save counter }
  258.     mov di,si
  259.     add di,8                { second value pointer }
  260.     @Loop2:
  261.       db 66h; mov ax,[di]   { load second Z distance }
  262.       db 66h; cmp ax,[si]
  263.       jle @Nothing
  264.       { Swap Z distances }
  265.       db 66h; mov bx,[si]
  266.       db 66h; mov [si],ax
  267.       db 66h; mov [di],bx
  268.       { Swap X coords }
  269.       mov ax,[si-4]
  270.       mov bx,[di-4]
  271.       mov [si-4],bx
  272.       mov [di-4],ax
  273.       { Swap Y coords }
  274.       mov ax,[si-2]
  275.       mov bx,[di-2]
  276.       mov [si-2],bx
  277.       mov [di-2],ax
  278.      {}
  279.     @Nothing:
  280.       add di,8
  281.     loop @Loop2
  282. @NoLoop:
  283.     mov cx,bp          { restore counter }
  284.     add si,8           { advance value pointer }
  285.   loop @Loop1          { loop it 47 times }
  286.   pop bp
  287. end;
  288.  
  289. var i,dist,xx,yy:integer; yes:boolean;
  290.  
  291. procedure Display;near;  { Displays the sorted balls }
  292. begin
  293.   if PutLogo then ximageput(@ml_bitmap,227,169,capag);
  294.   for i:=0 to 47 do begin
  295.     asm
  296.       mov si,i
  297.       shl si,3
  298.       mov ax,word ptr CPoints[si+4]
  299.       sub ax,270
  300.       sar ax,4
  301.       cmp ax,10
  302.       jle @Ok1
  303.       mov ax,10
  304.       jmp @Ok2
  305.     @Ok1:
  306.       test ax,ax
  307.       jge @Ok2
  308.       xor ax,ax
  309.     @Ok2:
  310.       mov dist,ax
  311.       mov ax,word ptr Cpoints[si]
  312.       mov word ptr xx,ax
  313.       mov ax,word ptr Cpoints[si+2]
  314.       mov word ptr yy,ax
  315.       {}
  316.       mov yes,1
  317.       cmp xx,0
  318.       jl @NoWay
  319.       cmp yy,0
  320.       jl @NoWay
  321.       cmp xx,303
  322.       jg @NoWay
  323.       jmp @Yeah
  324.     @NoWay:
  325.       mov yes,0
  326.     @Yeah:
  327.     end;
  328.     if yes then ximageovr(@ball[cball][dist],xx,yy,capag);{}
  329.     {xvplot(xx,yy,100,capag);{}
  330.   end;
  331. end;
  332.  
  333. Procedure DrawForm;near;assembler;
  334. asm
  335.     { Clear active page }
  336.     push capag
  337.     call xclrvpage
  338.     { 3D to 2D mapping }
  339.     mov si,offset CForm+2
  340.     mov ax,ds
  341.     mov es,ax
  342.     mov di,offset CPoints
  343.     mov cx,48
  344. @1: {X}
  345.     db 66h, 0Fh, 0BFh, 04h {movsx eax,word ptr [si]}
  346.     add si,2
  347.     db 66h; mov word ptr _3dx,ax
  348.     {Y}
  349.     db 66h, 0Fh, 0BFh, 04h {movsx eax,word ptr [si]}
  350.     add si,2
  351.     db 66h; mov word ptr _3dy,ax
  352.     {Z}
  353.     db 66h, 0Fh, 0BFh, 04h {movsx eax,word ptr [si]}
  354.     add si,2
  355.     db 66h; mov word ptr _3dz,ax
  356.     {}
  357.     db 66h; push cx
  358.     push si; push di
  359.     call IntMapCoordinates         { Do mapping }
  360.     pop di; pop si
  361.     db 66h; pop cx
  362.     mov ax,word ptr _2dx; stosw    { Store 2DX }
  363.     mov ax,word ptr _2dy; stosw    { Store 2DY }
  364.     db 66h; mov ax,word ptr Zt
  365.     db 66h; stosw  {stosd}         { Store Z distance }
  366.     dec cx
  367.     jnz @1
  368.     { Sort coordinates by Z distance }
  369.     call FastSort
  370.     { Display }
  371.     call Display
  372. end;
  373.  
  374. procedure FadeOut;near;assembler;  { Quick slides the palette to white }
  375. asm
  376.   push bp
  377.   mov cx,64
  378.   @Loop1:
  379.     mov bp,cx  { Save counter }
  380.     { "Increment" RGB fields }
  381.     mov cx,768
  382.     mov si,offset pal
  383.     mov di,si
  384.     @Loop2:
  385.       lodsb
  386.       inc al
  387.       cmp al,63
  388.       jbe @Ok1
  389.       mov al,63
  390.     @Ok1:
  391.       stosb
  392.     loop @Loop2
  393.     { Wait for some horizontal retraces }
  394.     mov cx,1 { 4 times = 4 scan lines }
  395.     @Loop6:
  396.       mov dx,3dah
  397.       @Loop3:
  398.         in al,dx
  399.         test al,1
  400.       jne @Loop3
  401.       @Loop4:
  402.         in al,dx
  403.         test al,1
  404.       je @Loop4
  405.     loop @Loop6
  406.     { Set new palette }
  407.     mov cx,256
  408.     mov si,offset pal
  409.     mov dx,3c8h
  410.     mov ah,0
  411.     @Loop5:
  412.        mov al,ah
  413.        out dx,al
  414.        inc dx
  415.        outsb
  416.        outsb
  417.        outsb
  418.        dec dx
  419.        inc ah
  420.     loop @Loop5
  421.     mov cx,bp  { Restore counter }
  422.   loop @Loop1  { Loop it 64 times }
  423.   pop bp
  424. end;
  425.  
  426. procedure FadeIn;near;assembler;  { Quick slides the palette from white to normal }
  427. asm
  428.   push bp
  429.   mov cx,64
  430.   @Loop1:
  431.     mov bp,cx  { Save counter }
  432.     { "Decrement" RGB fields }
  433.     mov cx,768
  434.     mov si,offset pal
  435.     mov di,offset origpal
  436.     @Loop2:
  437.       mov al,[si]
  438.       mov ah,[di]
  439.       cmp al,ah
  440.       je @Ok1
  441.       dec al
  442.       mov [si],al
  443.     @Ok1:
  444.       inc si
  445.       inc di
  446.     loop @Loop2
  447.     { Wait for vertical retrace }
  448.     mov dx,3dah
  449.     mov cx,128
  450.     @Loop6:
  451.       @Loop3:
  452.         in al,dx
  453.         test al,1
  454.       jne @Loop3
  455.       @Loop4:
  456.         in al,dx
  457.         test al,1
  458.       je @Loop4
  459.     loop @Loop6
  460.     { Set new palette }
  461.     mov cx,256
  462.     mov si,offset pal
  463.     mov dx,3c8h
  464.     mov ah,0
  465.     @Loop5:
  466.        mov al,ah
  467.        out dx,al
  468.        inc dx
  469.        outsb
  470.        outsb
  471.        outsb
  472.        dec dx
  473.        inc ah
  474.     loop @Loop5
  475.     mov cx,bp  { Restore counter }
  476.   loop @Loop1  { Loop it 64 times }
  477.   pop bp
  478. end;
  479.  
  480. var fc:word;
  481.  
  482. procedure accelerate;near;
  483. const freq = 70; {?}
  484. begin
  485.   port[$43]:=$36;
  486.   port[$40]:=lo($1234dc div freq);
  487.   port[$40]:=hi($1234dc div freq);
  488. end;
  489.  
  490. procedure unaccelerate;near;
  491. begin
  492.   port[$43]:=$36;
  493.   port[$40]:=$ff;
  494.   port[$40]:=$ff;
  495. end;
  496.  
  497. procedure my8_part1;interrupt;
  498. begin
  499.   asm
  500.     cli
  501.     db 66h; pusha
  502.     push es
  503.   end;
  504.   IncrAngle(RotAngle,RotStep);             { Increment angles of rotation }
  505.   IncrAngle(TiltAngle,TiltStep);
  506.   UpdateForm1;                             { Update current form (fine slides) }
  507.   inc(fc);
  508.   asm
  509.     pop es
  510.     mov al,20h
  511.     out 20h,al
  512.     db 66h; popa
  513.     sti
  514.   end;
  515. end;
  516.  
  517. procedure DoPart1;near;     { **** PART ONE **** }
  518. begin
  519.   { Init pages }
  520.   capag:=pagmin;
  521.   cvpag:=pagmax;
  522.   { Init angles' speeds }
  523.   RotStep:=2;
  524.   TiltStep:=3;
  525.   { Init form }
  526.   cformnr:=0;
  527.   Fcounter:=320;
  528.   fc:=0;
  529.   cball:=0;
  530.   move(form[cformnr],cformModel,sizeof(formtype));
  531.   move(form[cformnr],cform,sizeof(formtype));
  532.   old_int8:=intr[8];
  533.   accelerate;
  534.   intr[8]:=@my8_part1;
  535.   repeat
  536.     xvwait;                                  { Wait for vertical retrace }
  537.     xsetvpage(cvpag);                        { Set visual page }
  538.     DrawForm;                                { Draw form }
  539.     inc(capag); if capag>pagmax then capag:=pagmin;    { Advance pages }
  540.     inc(cvpag); if cvpag>pagmax then cvpag:=pagmin;
  541.   until keypressed or (fc>=2450+150);
  542.   if keypressed then readkey;
  543.   FadeOut;
  544.   intr[8]:=old_int8;
  545.   unaccelerate;
  546. end;
  547.  
  548. Procedure UpdateForm2;near;assembler;
  549. asm
  550.   mov cx,48
  551.   xor si,si
  552.   mov di,offset CForm + 2
  553.   @Loop1:
  554.     push cx {save counter}
  555.     { Increment Y index (using its speed) }
  556.     mov ax,word ptr YSpd[si]
  557.     mov bx,word ptr YIndex[si]
  558.     add bx,ax
  559.     cmp bx,MaxHeights-1
  560.     jle @Ok1
  561.     sub bx,bx
  562.   @Ok1:
  563.     mov word ptr YIndex[si],bx  { Update index }
  564.     { Extract height }
  565.     add bx,bx
  566.     mov ax,word ptr Y_Val[bx]
  567.     mov [di+2],ax  { Set Y }
  568.     { Increment radius (using its speed) }
  569.     mov ax,word ptr RadSpd[si]
  570.     mov bx,word ptr Rad[si]
  571.     add bx,ax
  572.     jge @Ok2
  573.     mov bx,0
  574.   @Ok2:
  575.     mov word ptr Rad[si],bx  { Update radius }
  576.     { Increment angle (using its speed) }
  577.     mov ax,word ptr AngSpd[si]
  578.     mov bx,word ptr Ang[si]
  579.     add bx,ax
  580.     jge @Ok4
  581.     add bx,360
  582.     jmp @Ok5
  583.   @Ok4:
  584.     cmp bx,359
  585.     jle @Ok5
  586.     sub bx,360
  587.   @Ok5:
  588.     mov word ptr Ang[si],bx  { Update angle }
  589.     { Compute X and Z coordinates }
  590.     shl bx,2
  591.     { X:=radius*cos(angle) }
  592.     db 66h; mov cx,word ptr CosTab[bx]
  593.     mov ax,word ptr Rad[si]
  594.     db 66h; cbw {cwde}
  595.     db 66h; imul cx
  596.     db 66h; sar ax,8 {Normalize}
  597.     mov [di],ax   { Set X coordinate }
  598.     { Z:=radius*sin(angle) }
  599.     db 66h; mov cx,word ptr SinTab[bx]
  600.     mov ax,word ptr Rad[si]
  601.     db 66h; cbw {cwde}
  602.     db 66h; imul cx
  603.     db 66h; sar ax,8 {Normalize}
  604.     mov [di+4],ax { Set Z coordinate }
  605.     { Update indexes }
  606.     add si,2
  607.     add di,6
  608.     pop cx
  609.   dec cx
  610.   jnz @Loop1
  611. end;
  612.  
  613. var kk:word;
  614.  
  615. procedure my8_part2;interrupt;
  616. begin
  617.   asm
  618.     cli
  619.     db 66h; pusha
  620.     push es
  621.   end;
  622.   UpdateForm2;                             { Update current form (fine slides) }
  623.   IncrAngle(RotAngle,RotStep);             { Increment angles of rotation }
  624.   IncrAngle(TiltAngle,TiltStep);
  625.   inc(FCounter);
  626.   if FCounter=300 then begin
  627.     for kk:=0 to 47 do repeat AngSpd[kk]:=Random(5) until AngSpd[kk]<>0;
  628.     FCounter:=301;
  629.   end;
  630.   if (FCounter>=900) and (FCounter<900+MaxH) then begin
  631.     for kk:=0 to MaxHeights-1 do if Y_Val[kk]>0 then dec(Y_Val[kk]);
  632.     if ObserverY<0 then inc(ObserverY);
  633.   end;
  634.   if (FCounter=1050+MaxH) then RotStep:=1;
  635.   if (FCounter=1650+MaxH) then
  636.     for kk:=0 to 47 do RadSpd[kk]:=-1;
  637.   asm
  638.     pop es
  639.     mov al,20h
  640.     out 20h,al
  641.     db 66h; popa
  642.     sti
  643.   end;
  644. end;
  645.  
  646. procedure DoPart2;near;  { **** PART TWO **** }
  647. var k:integer;
  648. begin
  649.   xclrvram;
  650.   for capag:=pagmin to pagmax do if PutLogo then ximageput(@ml_bitmap,227,169,capag);
  651.   FadeIn;
  652.   { Init }
  653.   capag:=pagmin;
  654.   cvpag:=pagmax;
  655.   SetAngles(0,110);
  656.   SetObserverPosition(0,40,300);
  657.   fillchar(Yindex,48*2,0);
  658.   fillchar(Ang,48*2,0);
  659.   fillchar(Rad,48*2,0);
  660.   for k:=0 to MaxHeights-1 do
  661.     Y_Val[k]:=Trunc(MaxH*sin(pi*k/MaxHeights));
  662.   randomize;
  663.   for k:=0 to 47 do begin
  664.     repeat YSpd[k]:=Random(5) until YSpd[k]>0;
  665.     rad[k]:=random(maxradius-40) + 40;
  666.     yindex[k]:=random(maxheights);
  667.     ang[k]:=random(360);
  668.   end;
  669.   cball:=1;
  670.   FCounter:=0;
  671.   RotStep:=0;
  672.   TiltStep:=0;
  673.   old_int8:=intr[8];
  674.   accelerate;
  675.   intr[8]:=@my8_part2;
  676.   repeat
  677.     xvwait;                                  { Wait for vertical retrace }
  678.     xsetvpage(cvpag);                        { Set visual page }
  679.     DrawForm;                                { Draw form }
  680.     inc(capag); if capag>pagmax then capag:=pagmin;    { Advance pages }
  681.     inc(cvpag); if cvpag>pagmax then cvpag:=pagmin;
  682.   until keypressed or (FCounter>=1650+MaxH+MaxRadius+50);
  683.   if keypressed then readkey;
  684.   FadeOut;
  685.   intr[8]:=old_int8;
  686.   unaccelerate;
  687. end;
  688.  
  689. begin
  690.   LoadData;
  691.   If AskMessage('Do you want to permanently see the ML logo ? (lower speed if Yes)') then
  692.     PutLogo:=true
  693.   else
  694.     PutLogo:=false;
  695.  
  696.   xinitvideo(0); pagmax:=3; {320x200/256/4pag}
  697.   xclrvram;
  698.   xsetpalette(@pal);
  699.  
  700.   { Init 3D engine }
  701.   Perspective:=True;
  702.   ZoomFactor:=250;
  703.   SetObserverPosition(0,0,300);
  704.   SetCamera(0,0,0);
  705.   SetAngles(0,0);
  706.  
  707.   DoPart1;   { Do the first part }
  708.   DoPart2;   { Do the second part }
  709.  
  710.   xclrvram;
  711.   FadeIn;
  712.  
  713.   xtextmode(25);
  714.   DoneAll;
  715. end.